<?php



final class BufStream {
	static $cached	= array() ;
	static $index	= 0 ;
	
	static function open($bu){
		$i			= self::$index ++ ;
		self::$cached[$i]	=& $bu ; 
		$path	= 'buf://' . $i . '/file.gz' ;
		$_fp		= gzopen( $path, 'r'); 
		return $_fp ;
	}
	
	var $pos ;
	var $len ;
	var $bu ;
	
	function stream_open($path, $mode, $options, &$opened_path) {
		$uri		= parse_url($path);
		$_key	= $uri['host']  ;
		$this->bu	=& self::$cached[$_key] ;
		$this->pos	 = 0;
		$this->len	 = strlen( $this->bu ) ;
		return true;
	}
	
	function stream_read($count) {
		$ret			=	substr($this->bu, $this->pos, $count);
		$this->pos 	+=	strlen($ret) ;
		return $ret ;
	}

	function stream_write($data) {
		return 0 ;
	}

	function stream_tell(){
		return $this->pos ;
	}

	function stream_eof() {
		return $this->pos >= $this->len ;
	}

	function stream_seek($offset, $whence) {
		 switch ($whence) {
			case SEEK_SET:
				if ( $offset < $this->len  && $offset >= 0) {
					$this->pos = $offset;
					return true;
				} else {
				     return false;
				}
				break;
                
			 case SEEK_CUR:
			 	$_pos	= $this->pos + $offset ;
				if ( $_pos >= 0 && $_pos <= $this->len ) {
					 $this->pos	= $_pos ; 
					return true;
				} else {
					return false;
				}
				break;
                
			case SEEK_END:
				$_pos	= $this->len	+ $offset ;
				if ( $_pos >= 0 && $_pos <=  $this->len) {
					$this->pos = $_pos ;
					return true ;
				} else {
					return false ;
				}
				break;
                
			default:
				return false;
		}
	}
	
	function stream_cast( $cast_as ){
		print_r($cast_as );
	}
}

stream_wrapper_register("buf", "BufStream")  or die("Failed to register protocol");



final class Curl{

	static $ff_headers = array(
			'User-Agent'		=> 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3' ,
			'Accept'			=> 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' ,
			'Accept-Language'	=> 'en-us' ,
			'Accept-Encoding'	=> 'gzip,deflate' ,
			'Accept-Charset'		=> 'GB2312,utf-8;q=0.7,*;q=0.7' ,
		);
	
	var $_scheme	= '' ;
	var $_host		= '' ;
	var $_port		= 0 ;
	var $_path		= '' ;
	
	var $_garg		= array() ;
	var $_parg		= array() ;
	var $_header	= array() ;
	var $_cookie	= array() ;
	
	var $_fp		= null ;

	function __construct ($url){
		$uri		= parse_url($url);
		$this->_host	= $uri['host'] ;
		$this->_path	= $uri['path'] ;
		
		if( $uri['port'] ){
			$this->_port = (int) $uri['port'] ;
		}
		if( $this->_port  < 10 || $this->_port > 65535 ){
			$this->_port = 80 ;
		}
		if( !empty($uri['query']) ){
			parse_str($uri['query'], $this->_garg);
		}
		
		if( $uri['scheme'] ){
			$this->_scheme	= $uri['scheme'] ;
		}else{
			$this->_scheme	= 'http' ;
		}
		
		$this->header( self::$ff_headers );
	}

	function __destruct() {
		
	}

	static private function _set_ary(&$ary, &$key , $val ){
		if( is_string($key) ){
			if( is_null($val) ){
				unset($ary[$key] );
			}else{
				$ary[$key]	= $val ;
			}
		}else if( is_array($key) ){
			foreach($key as $k => $v){
				$ary[$k]	= $v ;
			}
		}
	}

	function get( $key, $val  = null ){
		self::_set_ary($this->_garg, $key, $val );
	}

	function post( $key, $val  = null ){
		self::_set_ary($this->_parg, $key, $val );
	}
	
	function header( $key, $val  = null ){
		self::_set_ary($this->_header, $key, $val );
	}
	
	function cookie( $key, $val  = null ){
		self::_set_ary($this->_cookie, $key, $val );
	}

	function context(){
		$options	= array();
		$options[$this->_scheme]	= array(
				'method'	=> 'GET' ,
				'header'	=> '' ,
			);
		
		$content	= null ;
		
		if( !empty($this->_parg) ){
			$options[$this->_scheme]['method']	=	'POST ' ;
			$content	= http_build_query( $this->_parg ) ;
			$options[$this->_scheme]['content']	=	$content ;
			
		}

		
		$header		= array() ;
		
		//$header['Host']	= $this->_host  ;
		
		foreach($this->_header as $k => $v ){
			$header[$k]	= $v ;
		}
		
		
		if( !empty( $this->_cookie) ){
			$_cookie	= array() ;
			foreach($this->_cookie as $k => $v ){
				$_cookie[]	 = $k . '=' . $v ;
			}
			$header['Cookie']	= join('; ', $_cookie )  ;
		}
		
		if( $content  ){
			$header['Content-length']	=   strlen($content) ;
		}
		$header['Connection']	= 'close' ;
		
		foreach($header as $k => $v ){
			$options[$this->_scheme]['header']	.= $k . ': ' . $v . "\r\n";
		}
		
		return stream_context_create($options)  ;
	}
	
	function url(){
		$url	= $this->_scheme . '://' .  $this->_host ;
		if( $this->_port != 80 ){
			$url	.= ':' . $this->_port  ;
		}
		$url	.=   $this->_path ;
		if( !empty($this->_garg) ){
			$url	.= '?' . http_build_query($this->_garg) ;
		}
		return $url ;
	}
	
	function read(){
		$this->_fp	= fopen( $this->url() , 'r', false, $this->context()  ) ;
		
		$da		=  stream_get_contents($this->_fp	, -1);
		$me		= stream_get_meta_data ($this->_fp );
		
		foreach($me['wrapper_data'] as $v ){
			$i	= strpos ($v, 'Content-Encoding') ;
			if( $i !== false ){
				$_v	= trim( substr($v, 17) );
				if( $_v == 'gzip' ){
					$_path	= tempnam ('.', 'gz') ;
					file_put_contents($_path,  $da);
					$_fp		=  gzopen($_path,  'r'); 
					$_da 	= gzread($_fp	, 10000 );
					while ( !gzeof($_fp) ) {
					  	$_da 	.= gzread($_fp	, 10000 );
					}
					gzclose($_fp) ;
					unlink( $_path );
					return $_da ;
				}
			}
		}
		return $da ;
	}
}

?>